/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.enrstu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.enrstu.domain.ChildrenInformation;
import me.zhengjie.modules.enrstu.repository.ChildrenInformationRepository;
import me.zhengjie.modules.enrstu.service.ChildrenInformationService;
import me.zhengjie.modules.enrstu.service.dto.*;
import me.zhengjie.modules.enrstu.service.mapstruct.ChildrenInformationMapper;
import me.zhengjie.utils.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author yyx
* @date 2024-11-01
**/
@Slf4j
@Service
@RequiredArgsConstructor
public class ChildrenInformationServiceImpl implements ChildrenInformationService{
    private final RabbitTemplate rabbitTemplate;
    private final ChildrenInformationRepository childrenInformationRepository;
    private final ChildrenInformationMapper childrenInformationMapper;



    @Override
    @Transactional
    public ChildrenInformationDto findById(String id) {
        ChildrenInformation childrenInformation = childrenInformationRepository.findById(id).orElseGet(ChildrenInformation::new);
        ValidationUtil.isNull(childrenInformation.getId(),"ChildrenInformation","id",id);
        return childrenInformationMapper.toDto(childrenInformation);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChildrenInformation create(ChildrenInformation resources,Boolean isSubmit) {

        //校验：同一所意向学校，儿童信息是否重复存在，使用身份证+意向学校进行判断
        if (!ObjectUtil.isNull(resources.getChildrenIdentityCard())) {
            if (childrenInformationRepository.count((Root<ChildrenInformation> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
                Predicate childrenIdentityCard = cb.equal(root.get("childrenIdentityCard"), resources.getChildrenIdentityCard());
                Predicate schoolId = cb.equal(root.get("schoolId"), resources.getSchoolId());
                return cb.and(childrenIdentityCard, schoolId);
            }) > 0) {
                throw new BadRequestException(resources.getChildrenName() + "儿童的信息已存在意向学校中，无需重复提交！");
            }
        }
        resources.setCliId(String.valueOf(SecurityUtils.getCurrentUserId()));
        resources.setId(IdUtil.simpleUUID());
        ChildrenInformation childrenInfo = childrenInformationRepository.save(resources);
        if (isSubmit){
            this.submitCheck(childrenInfo);
        }
        return childrenInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SignUpChildrenInfoCreateOrUpdate resources,Boolean isSubmit) {
        ChildrenInformation childrenInformation = childrenInformationRepository.findById(resources.getId()).orElseGet(ChildrenInformation::new);
        ValidationUtil.isNull( childrenInformation.getId(),"ChildrenInformation","id",resources.getId());
        BeanUtils.copyProperties(resources,childrenInformation);
        ChildrenInformation save = childrenInformationRepository.save(childrenInformation);
        if (isSubmit){
            this.submitCheck(save);
        }
    }

    @Override
    public void update(ChildrenInformation resources) {
        ChildrenInformation childrenInformation = childrenInformationRepository.findById(resources.getId()).orElseGet(ChildrenInformation::new);
        ValidationUtil.isNull( childrenInformation.getId(),"ChildrenInformation","id",resources.getId());
        BeanUtils.copyProperties(resources,childrenInformation);
        childrenInformationRepository.save(childrenInformation);
    }

    @Override
    public List<ChildrenInformationDto> findByCliId(String cliId) {
        return childrenInformationMapper.toDto(childrenInformationRepository.findByCliId(cliId));
    }
    private void submitCheck(ChildrenInformation childrenInformation){
        //1.监护人与儿童是否在同一户口本上
        if (ObjectUtil.equal(childrenInformation.getIsGuardianSomeHuKouBoot(),1)){
            //判断填报信息是保存还是提交操作，保存不需要校验，而提交需要
            throw new BadRequestException("适龄儿童与监护人不在同一户口本，无法进行提交，请前往户籍管理地进行迁移!");
        }
        //（2）儿童信息
        BeanUtil.beanToMap(childrenInformation, false, false).forEach((key, value)->{
            if (ObjectUtil.equal(key, "id") || ObjectUtil.equal(key, "infId") || ObjectUtil.equal(key, "gmtCreate") || ObjectUtil.equal(key, "gmtModified")){
                return;
            }
            if (ObjectUtil.isNull(value)){
                throw  new BadRequestException("请确保所有必填项填写完成后提交" + key);
            }
        });
    }

}